package com.mariusz.managers;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.table.DefaultTableModel;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import com.mariusz.data.DataContainer;
import com.mariusz.data.XmlDataConatiner;
import com.mariusz.data.dto.Property;
import com.mariusz.data.dto.Rentier;
import com.mariusz.data.dto.Room;
import com.mariusz.data.enums.PaymentsIntervals;
import com.mariusz.exceptions.ReadDataException;
import com.mariusz.ui.models.PaymentsTableModel;
import com.mariusz.ui.models.RentiersTableModel;

public class DataManager {

	private static DataManager instance = new DataManager();
	private DataContainer dataContainer;
	private XmlDataConatiner xmlDataConainer;
	private Property currentProperty;
	private Rentier currentRentier;
	private String dataFile = "manager.ser";
	private static final String[] RENTIERS_TABLE_HEADER = new String[] {
			"Name", "Phone", "Property Name", "Room" };

	public static DataManager getInstance() {
		return instance;
	}
	
	public DataContainer getDataContainer(){
		return dataContainer;
	}

	public void persistData() throws IOException {
//		FileOutputStream fos = new FileOutputStream(dataFile);
//		ObjectOutputStream oos = new ObjectOutputStream(fos);
//		oos.writeObject(dataContainer);
//		oos.close();

		xmlDataConainer = new XmlDataConatiner();
		xmlDataConainer.setProperties(dataContainer.getProperties());
		xmlDataConainer.setRentiers(dataContainer.getRentiers());
		
		try {
			JAXBContext context = JAXBContext.newInstance(XmlDataConatiner.class);
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			FileOutputStream foss = new FileOutputStream(dataFile + ".xml");
			m.marshal(xmlDataConainer, foss);
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void retriveData() throws IOException, ReadDataException {
		XmlDataConatiner xmlDataContainer = null;
		try {
			JAXBContext context = JAXBContext.newInstance(XmlDataConatiner.class);
			Unmarshaller m = context.createUnmarshaller();
			FileInputStream fiss = new FileInputStream(dataFile + ".xml");
			xmlDataContainer = (XmlDataConatiner) m.unmarshal(fiss);
		} catch (Exception e) {
			
		}
		if (xmlDataContainer == null) {
			FileInputStream fis = new FileInputStream(dataFile);
			ObjectInputStream ois = new ObjectInputStream(fis);
			try {
				dataContainer = (DataContainer) ois.readObject();
				ois.close();
			} catch (ClassNotFoundException e) {
				throw new ReadDataException(e);
			}
		}else{
			dataContainer = new DataContainer();
			dataContainer.setProperties(xmlDataContainer.getProperties());
			dataContainer.setRentiers(xmlDataContainer.getRentiers());
		}

	}

	public void setContainer(DataContainer container) {
		dataContainer = container;
	}

	public void setMockData() {

		List<Property> properties = new ArrayList<Property>();
		dataContainer.setProperties(properties);
		List<Rentier> rentiers = new ArrayList<Rentier>();
		dataContainer.setRentiers(rentiers);
	}

	public List<Property> getProperties() {
		return dataContainer.getProperties();

	}

	public List<Rentier> getRentiers() {
		return dataContainer.getRentiers();

	}

	public RentiersTableModel getRentiersTableModel() {
		RentiersTableModel model = new RentiersTableModel(getRentiers());
		return model;
	}

	public ListModel toRoomsListModel(List<Room> rooms) {
		DefaultListModel listModel = new DefaultListModel();
		for (Room room : rooms) {
			listModel.addElement(room);
		}
		return listModel;
	}

	public void setCurrentProperty(Property currentProperty) {
		this.currentProperty = currentProperty;
	}

	public Property getCurrentProperty() {
		return currentProperty;
	}

	public void setCurrentRentier(Rentier rentier) {
		currentRentier = rentier;
	}

	public Rentier getCurrentRentier() {
		return currentRentier;
	}

	public PaymentsTableModel toPaymentsModel(Rentier rentier) {
		PaymentsTableModel model = new PaymentsTableModel(rentier.getPayments());
		return model;
	}
}
